package com.zijidelu.luframework.infrastructure.persistence.repository.core.domain.calculator;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.zijidelu.luframework.utils.CastUtil;
import com.zijidelu.luframework.base.model.PO;
import com.zijidelu.luframework.config.properties.LuFrameworkProperties;
import com.zijidelu.luframework.constant.ClassNameConstant;
import com.zijidelu.luframework.constant.DomainConstant;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 领域键计算抽象类。
 *
 * @author ZIJIDELU
 * @date: 2024/4/23 9:50
 */
public abstract class AbstractDomainKeyCalculator<P extends PO> implements DomainKeyCalculator {
    /**
     * 实体类型。
     */
    protected final Class<P> entityClass = CastUtil.cast(ReflectionKit.getSuperClassGenericType(
            this.getClass(),
            AbstractDomainKeyCalculator.class, 0)
    );

    @Setter(onMethod_ = {@Autowired})
    private LuFrameworkProperties luFrameworkProperties;

    /**
     * 领域名称
     */
    private String domainName;

    /**
     * 领域前缀
     */
    private String domainPrefix;

    /**
     * 处理实体类名称，移除常见后缀
     *
     * @param entityName 原始实体类名称
     * @return 处理后的实体类名称
     */
    private static String calcDomainName(String entityName) {
        String result = entityName;

        // 检查并移除后缀
        for (String suffix : ClassNameConstant.DATA_MODEL_SUFFIXES) {
            if (result.endsWith(suffix)) {
                result = result.substring(0, result.length() - suffix.length());
                break; // 只移除一个后缀，避免连续移除
            }
        }

        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getDomainName() {
        if (Objects.isNull(this.domainName)) {
            this.domainName = Objects.requireNonNull(StrUtil.toUnderlineCase(calcDomainName(entityClass.getSimpleName())))
                    .toUpperCase();
        }

        return this.domainName;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getDomainPrefix() {
        if (Objects.isNull(this.domainPrefix)) {
            this.domainPrefix = buildDomainPrefix();
        }
        return this.domainPrefix;
    }

    /**
     * 构建域前缀
     * 格式: {applicationName}:{DOMAIN_PREFIX}:{domainName}
     */
    private String buildDomainPrefix() {
        return String.join(
                DomainConstant.DOMAIN_SPLIT,
                luFrameworkProperties.getApplicationName(),
                DomainConstant.CORE_DOMAIN_PREFIX,
                getDomainName()
        );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String calcDomainKey(String... params) {
        return calcDomainKey(Arrays.asList(params));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String calcDomainKey(List<String> paramList) {
        // 创建新列表避免修改原列表
        List<String> keyParts = new ArrayList<>();
        keyParts.add(getDomainPrefix());
        keyParts.addAll(paramList);

        return String.join(DomainConstant.DOMAIN_SPLIT, keyParts);
    }

}
